#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
photocomment Simple tool for editing image exif comments.

 Author: Juuso Räsänen
 Lincense: GPL version 2

"""

import pyexiv2
import sys
import os
import argparse
from subprocess import Popen, PIPE
import time
import glob
from photodb import IMAGE_EXTENSIONS

#from Tkinter import *
#import tkSimpleDialog

#COMMENT_KEY = 'Xmp.dc.description'
COMMENT_KEY = 'Exif.Image.ImageDescription'
RATING_KEY = 'Xmp.xmp.Rating'



class MyDialog:
    def __init__(self, parent):

        top = self.top = Toplevel(parent)

        Label(top, text="Value").pack()

        self.e = Entry(top)
        self.e.pack(padx=5)

        b = Button(top, text="OK", command=self.ok)
        b.pack(pady=5)

    def ok(self):

        print "value is", self.e.get()

        self.top.destroy()


#EXTS = ['.jpg', '.nef', '.tiff', '.tif']


def getSideCars(fname):
    """ Return list of files that are "sidecars" for the given file. """
    # First, find the basename of the given file
    basename, extension = splitext(fname)

    # Then, find all files with the same basename.
    sidecars0 = glob.glob(basename + '*')

    # And finally, select only image files.
    sidecars = []
    for f in sidecars0:
        bn, ext = os.path.splitext(f)
        ext = ext.lstrip('.').lower()
        if (ext in IMAGE_EXTENSIONS):
            sidecars.append(f)

    if (len(sidecars) == 0):
        sys.stderr.write("Warning, total of 0 real sidecar files found for " + fname + "\n")

    return sidecars


def splitext(fname):
    """ Like os.path.splitext but use the second last dot instead of the last one. """
    basename0, ext0 = os.path.splitext(fname)
    basename1, ext1 = os.path.splitext(basename0)
    return [basename1, ext1 + ext0]
    


def getComment(fname):
    """ Get the image comment from Exif metadata. """
    try:
        metadata = pyexiv2.ImageMetadata(fname)
        metadata.read()
        #return metadata[COMMENT_KEY].value['x-default']
        return metadata[COMMENT_KEY].value
    except Exception, msg:
        sys.stderr.write('%s\n' % msg)
        return ""

def setCommentSingle(fname, newComment):
    try:
        metadata = pyexiv2.ImageMetadata(fname)
        metadata.read()

        #newTag = dict()
        #newTag['x-default'] = unicode(newComment, encoding=sys.getfilesystemencoding())
        #metadata[COMMENT_KEY] = pyexiv2.XmpTag(COMMENT_KEY, newTag)
        metadata[COMMENT_KEY] = newComment

        metadata.write()
    except Exception, msg:
        sys.stderr.write('%s\n' % msg)
        sys.stderr.write("Unable to set comment for " + fname + "\n")


def setComment(fname, newComment, sideCarsToo=True):
    """ Set the image comment in Exif metadata. """

    if (sideCarsToo):
        allFilesToSet = getSideCars(fname)
        for fn in allFilesToSet:
            setCommentSingle(fn, newComment)

        print allFilesToSet
    else:
        setCommentSingle(fname, newComment)
        print fname


def setRatingSingle(fname, rating):
    rating = int(rating)

    try:
        metadata = pyexiv2.ImageMetadata(fname)
        metadata.read()
        metadata[RATING_KEY] = rating
        metadata.write()
    except Exception, msg:
        sys.stderr.write('%s\n' % msg)
        sys.stderr.write("Unable to set rating for " + fname + "\n")

def setRating(fname, rating, sideCarsToo=True):
    """ Set the image rating in Exif metadata. """
    if (sideCarsToo):
        allFilesToSet = getSideCars(fname)
        for fn in allFilesToSet:
            setRatingSingle(fn, rating)

        print allFilesToSet
    else:
        setRatingSingle(fname, rating)
        print fname


def edit(oldComment):
    """ Open a user dialog for editing comment. """

    command = 'zenity --entry --entry-text="' + oldComment + '" --width 500 --text="Modify the comment" --title="Set new comment..."'
    p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()
    if (p.returncode != 0):
        return [oldComment, False]
    return stdout.rstrip(), True


def editTk(oldComment):
    """ Open a user dialog for editing comment. """

    root = Tk()
    root.title('Set new comment!')

    Label(root, text="Value").pack()

    e = Entry(root)
    e.pack(padx=10, pady=10)
    e.delete(0, END)
    e.insert(0, oldComment)

    b = Button(root, text="OK")
    b.pack()

    root.mainloop()
    return [oldComment, False]

def main():

    parser = argparse.ArgumentParser(description='photocomment', epilog="Author: Juuso Räsänen")
    parser.add_argument('fname', nargs='*', help="fname")
    parser.add_argument('-debug', '-d', action='store_true', help='Print some additional debug info')
    parser.add_argument('-nosidecars', action='store_true', help="Don't modify sidecars files")

    parser.add_argument('-editcomment', action='store_true', help='Edit comment')
    parser.add_argument('-setcomment', help='Set new comment')
    parser.add_argument('-setrating', help='Set new rating')

    args = parser.parse_args()

    for fname in args.fname:
        
        if (args.setcomment):
            setComment(fname, args.setcomment, not args.nosidecars)
        elif (args.editcomment):
            #print comment
            [newComment, edited] = edit(getComment(fname))
            if (edited):
                setComment(fname, newComment, not args.nosidecars)
        elif (args.setrating):
            setRating(fname, args.setrating)

        else:
            print getComment(fname)


if __name__ == "__main__":
    main()
 
    #print sys.argv[2]
    #editTk(getComment(sys.argv[2]))
    if (0):    
        root = Tk()
        root.title('Set new comment')

        text = Text(root, height=26, width=50).pack(padx=10, pady=10)
        root.mainloop()

        #d = MyDialog(root)
        #root.wait_window(d.top)

